package cn.exrick.xboot.base.serviceimpl

import cn.exrick.xboot.base.dto.*
import cn.exrick.xboot.base.entity.EnterpriseEmployee
import cn.exrick.xboot.base.entity.EnterpriseUser
import cn.exrick.xboot.base.entity.SecurityAdvisor
import cn.exrick.xboot.base.entity.SupervisionUser
import cn.exrick.xboot.base.mapper.SupervisionUserMapper
import cn.exrick.xboot.base.service.*
import cn.exrick.xboot.base.vo.*
import cn.exrick.xboot.core.common.constant.CommonConstant
import cn.exrick.xboot.core.common.utils.PageUtil
import cn.exrick.xboot.core.common.utils.ResultUtil
import cn.exrick.xboot.core.common.utils.ResultUtil.*
import cn.exrick.xboot.core.common.utils.SecurityUtil
import cn.exrick.xboot.core.common.utils.ToolUtil
import cn.exrick.xboot.core.common.vo.PageVo
import cn.exrick.xboot.core.common.vo.Result
import cn.exrick.xboot.core.dao.RoleDao
import cn.exrick.xboot.core.entity.Role
import cn.exrick.xboot.core.entity.User
import cn.exrick.xboot.core.entity.UserRole
import cn.exrick.xboot.core.service.RoleService
import cn.exrick.xboot.core.service.UserService
import cn.exrick.xboot.core.service.mybatis.IUserRoleService
import com.baomidou.mybatisplus.core.toolkit.Wrappers
import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
import com.google.common.collect.Maps
import lombok.SneakyThrows
import lombok.extern.slf4j.Slf4j
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.util.*
import javax.annotation.Resource

/**
 * 监管部门用户接口实现
 * @author Fei
 */
@Slf4j
@Service
@Transactional
open class ISupervisionUserServiceImpl : ServiceImpl<SupervisionUserMapper?, SupervisionUser?>(), ISupervisionUserService {

    @Autowired
    private val userService: UserService? = null

    @Autowired
    private val userRoleService: IUserRoleService? = null

    @Autowired
    private val securityUtil: SecurityUtil? = null

    @Autowired
    private val areaService: IAreaService? = null

    @Autowired
    private val roleService: RoleService? = null

    @Autowired
    private val iEnterpriseUserService: IEnterpriseUserService? = null

    @Autowired
    private val iSecurityAdvisorService: ISecurityAdvisorService? = null

    @Autowired
    private val iAdministrativeOfficeService: IAdministrativeOfficeService? = null

    @Autowired
    private lateinit var iBusinessService: IBusinessService

    @Autowired
    private lateinit var iEnterpriseEmployeeService: IEnterpriseEmployeeService

    @Autowired
    private lateinit var iUserRoleService: IUserRoleService

    @Autowired
    private lateinit var iAreaService: IAreaService

    @Autowired
    private lateinit var iDutyService: IDutyService

    @Autowired
    private lateinit var roleDao: RoleDao

    override fun getSecurityAdvisorByAreaId(securityAdvisorSearchDto: SecurityAdvisorSearchDto, pageVo: PageVo?): Result<MutableMap<String, Any?>>? {

        return ToolUtil.setListToNul(iSecurityAdvisorService!!.list(KtQueryWrapper(SecurityAdvisor::class.java).eq(SecurityAdvisor::areaId, securityUtil!!.currUser.areaId)
                .eq(ToolUtil.isNotEmpty(securityAdvisorSearchDto.businessId), SecurityAdvisor::businessIds, securityAdvisorSearchDto.businessId)
                .orderByDesc(SecurityAdvisor::createTime)))?.run {

            var securityAdvisorList = mapNotNull { iSecurityAdvisorService.getSecurityAdvisorListVo(it?.id!!) }.toMutableList()


            if (ToolUtil.isNotEmpty(securityAdvisorSearchDto.companyType))
                securityAdvisorList = securityAdvisorList.filter { it.companyType == securityAdvisorSearchDto.companyType }.toMutableList()

            val result: MutableMap<String, Any?> = Maps.newHashMap()
            result["size"] = securityAdvisorList.size
            result["content"] = PageUtil.listToPage(pageVo, securityAdvisorList)

            data(result, "获取安全顾问列表成功")
        } ?: error(201,"暂无数据")
    }


    @SneakyThrows
    override fun createSupervisionUser(supervisionUserDto: SupervisionUserDto?): Result<Any?>? {

        return supervisionUserDto?.let {


            if (ToolUtil.isNotEmpty(userService!!.findByMobile(it.mobile))) {

                return error("当前手机号已经存在!")
            }

            //用户基础信息
            val userInsert = userService.save( User().apply {
                ToolUtil.copyProperties(supervisionUserDto, this)
                areaId = securityUtil!!.currUser.areaId
                username = it.mobile
                password = BCryptPasswordEncoder().encode(it.password)
                createBy = securityUtil.currUser.id
            })

            //用户角色信息
            val userRole = UserRole()
            when (it.departmentAccount) {

                true -> {

                    userRole.apply {

                        userId = userInsert.id
                        roleId = roleService!!.getRoleIdByRoleName(when (iAreaService.getById(securityUtil!!.currUser.areaId)?.areaLevel) {
                            1 -> {
                                CommonConstant.ROLE_CITY_SYSTEM
                            }
                            2 -> {
                                CommonConstant.ROLE_COUNTY_SYSTEM
                            }
                            else -> {
                                CommonConstant.ROLE_TOWN_SYSTEM
                            }
                        })
                        userRoleService!!.save(this)
                    }
                }
                else -> {

                   it.roleIds?.split(",")?.forEach {

                       userRoleService!!.save(UserRole().apply {

                           userId = userInsert.id
                           roleId = it
                       })
                   }
                }
            }

            //监管部门信息
            val supervisionUser = SupervisionUser()
            ToolUtil.copyProperties(supervisionUserDto, supervisionUser)

            supervisionUser.userLevel = areaService!!.getById(securityUtil!!.currUser.areaId)?.areaLevel
            supervisionUser.userId = userInsert.id
            supervisionUser.areaId = securityUtil.currUser.areaId
            return if (save(supervisionUser)) {

                success("添加监管部门成功！")
            } else {

                error("添加失败！")
            }

        }
    }

    override fun updateSupervisionUser(supervisionUserDto: SupervisionUserDto?): Result<Any?>? {

         return supervisionUserDto?.let {


             getById(it.id)?.let {

                 //1.修改用户信息
                 userService!!.get(it.userId)?.apply {

                     ToolUtil.copyProperties(it, this)
                     id = it.userId
                     userService.update(this)


                     //2.角色
                     userRoleService!!.removeUserRolesByUserId(it.userId)
                     supervisionUserDto.roleIds?.split(",")?.forEach {roleIdStr ->

                         userRoleService.save(UserRole().apply {

                             userId = it.userId
                             roleId = roleIdStr
                         })
                     }

                 }

                 //3. 监管部门信息
                 ToolUtil.copyProperties(supervisionUserDto, it)
                 it.userLevel = areaService!!.getById(supervisionUserDto.areaId)?.areaLevel
                 updateById(it)
             }

             success("更新成功")
        }
    }

    override fun removeSupervisionUser(ids: Array<out String>): Result<Any?>? {

        ids.toList().forEach { id: String? ->
            Optional.ofNullable(getById(id)).ifPresent { supervisionUser: SupervisionUser ->

                //1.删除用户
                userService!!.delete(supervisionUser.userId)
                //3. 删除监管部门用户
                removeById(supervisionUser.id)
                /*//2. 删除角色
                userRoleService!!.remove(Wrappers.lambdaQuery<UserRole>().eq({ obj: UserRole -> obj.userId }, supervisionUser.userId))*/
            }
        }
        return success("移除监管部门用户成功！")
    }

    override fun getSupervisionUserList(supervisionUserDto: SupervisionUserDto?, pageVo: PageVo?): Result<MutableMap<String, Any>>? {

        return supervisionUserDto?.let {

            if (!userRoleService!!.findByUserId(securityUtil!!.currUser.id)?.map { it.id }?.contains(roleService!!.getRoleIdByRoleName(CommonConstant.ROLE_ADMIN))!!) {

                getOne(KtQueryWrapper(SupervisionUser::class.java).eq(SupervisionUser::userId, securityUtil.currUser.id))?.apply {

                    it.userLevel = userLevel
                }
            }

            val result: MutableMap<String, Any> = Maps.newHashMap()

            return getSupervisionUserList(it)?.let {

                result["size"] = it.size
                result["content"] = PageUtil.listToPage(pageVo, it)

                data(result, "获取监管部门列表数据成功")
            } ?: error(201, "暂无数据")
        }
    }

    /**
     * 私有方法: 获取监管部门用户列表
     */
    private fun getSupervisionUserList(supervisionUserDto: SupervisionUserDto): MutableList<SupervisionUserVo?>? {

        val supervisionWrapper = KtQueryWrapper(SupervisionUser::class.java)
                .eq(SupervisionUser::userLevel, areaService!!.getById(securityUtil!!.currUser.areaId)?.areaLevel)
                .eq(SupervisionUser::createBy, securityUtil.currUser.id)
                .orderByAsc(SupervisionUser::createTime)

        supervisionUserDto.let {

            if (it.officeId != null && it.officeId != "") {

                supervisionWrapper.like(SupervisionUser::officeId, it.officeId)
            }

            if (it.dutyId != null && it.dutyId != "") {

                supervisionWrapper.like(SupervisionUser::dutyId, it.dutyId)
            }
        }

        return ToolUtil.setListToNul(list(supervisionWrapper))?.let { supervisionUserList ->

            var supervisionUserVoList = supervisionUserList.map { it?.let { getSupervisionUserVo(it) } }.toMutableList()

            supervisionUserDto.apply {

                if (mobile != null && mobile != "") {

                    supervisionUserVoList = supervisionUserVoList.filter { supervisionUserVo -> supervisionUserVo!!.mobile!!.contains(mobile!!) }.toMutableList()
                }
                if (areaId != null && areaId != "") {

                    supervisionUserVoList = supervisionUserVoList.filter { supervisionUserVo -> supervisionUserVo!!.areaId!! == areaId }.toMutableList()
                }

            }

            return@let supervisionUserVoList
        }

    }

    override fun getSupervisionInfo(): Result<SupervisionUserInfoVo?>? {

        return data(SupervisionUserInfoVo().apply {

            ToolUtil.copyProperties(securityUtil!!.currUser, this)

            getOne(KtQueryWrapper(SupervisionUser::class.java).eq(SupervisionUser::userId, securityUtil.currUser.id))?.let {

                ToolUtil.copyProperties(it, this)
                officeName = iAdministrativeOfficeService!!.getOfficeNameById(officeId)
                userLevelStr = when (it.userLevel) {
                    1 -> {
                        "市级部门"
                    }
                    2 -> {

                        "县区部门"
                    }
                    else -> {

                        "乡镇部门"
                    }
                }
                roleName = iUserRoleService.findByUserId(securityUtil.currUser.id).map { it.name }.joinToString(",")
            }
        }, "获取个人信息成功")
    }

    override fun getSupervisionExamByLevel(areaId: String?): Result<List<UserCommonVo>>? {

        return this.list(KtQueryWrapper(SupervisionUser::class.java)
                .eq(SupervisionUser::areaId, if (ToolUtil.isNotEmpty(areaId)) areaId else securityUtil!!.currUser.areaId)
                .orderByDesc(SupervisionUser::createTime))?.run {


            val supervisionList = filter { iUserRoleService.findByUserId(it?.userId).map { it.id }.contains(when (iAreaService.getById(securityUtil!!.currUser.areaId)?.areaLevel) {

                2 -> {
                    CommonConstant.ROLE_COUNTY_EXAM_SUPERVISION
                }
                else -> {
                    CommonConstant.ROLE_TOWN_EXAM_SUPERVISION
                }
            })
                    || iUserRoleService.findByUserId(it?.userId).map { it.id }.contains(roleService!!.getRoleIdByRoleName(when (iAreaService.getById(securityUtil.currUser.areaId)?.areaLevel) {
                2 -> {
                    CommonConstant.ROLE_COUNTY_EXAM_SUPERVISION
                }
                else -> {
                    CommonConstant.ROLE_TOWN_EXAM_SUPERVISION
                }
            }) )}

            return data(mapNotNull { UserCommonVo().apply { ToolUtil.copyProperties(userService!!.get(it?.userId), this) }  }, "获取数据成功！")

        } ?: error(201, "暂无数据")
    }

    override fun getSupervisionCheckByArea(areaId: String): Result<List<UserCommonVo>>? {

        return this.list(KtQueryWrapper(SupervisionUser::class.java)
                .eq(SupervisionUser::areaId, if (ToolUtil.isNotEmpty(areaId)) areaId else securityUtil!!.currUser.areaId)
                .orderByDesc(SupervisionUser::createTime))?.run {


            val supervisionList = filter { iUserRoleService.findByUserId(it?.userId).map { it.name }.contains(when (iAreaService.getById(if (ToolUtil.isNotEmpty(areaId)) areaId else securityUtil!!.currUser.areaId)?.areaLevel) {

                2 -> {
                    CommonConstant.ROLE_COUNTY_ENTERPRISE_ANDITOR
                }
                else -> {
                    CommonConstant.ROLE_TOWN_ENTERPRISE_ANDITOR
                }
            } ) }

            if (ToolUtil.isNotEmpty(ToolUtil.setListToNul(supervisionList))) {

                return data(supervisionList.mapNotNull { UserCommonVo().apply { ToolUtil.copyProperties(userService!!.get(it?.userId), this) }  }, "获取数据成功！")
            } else {

                error(201, "暂无数据！")
            }

        }

    }

    /**
     * 私有方法: 获取监管部门详情信息
     */
    private fun getSupervisionUserVo(supervisionUser: SupervisionUser): SupervisionUserVo {

        val supervisionUserVo = SupervisionUserVo()

        userService!!.get(supervisionUser.userId)?.let {

            supervisionUserVo.apply {

                ToolUtil.copyProperties(it, this)
                ToolUtil.copyProperties(supervisionUser, this)
                areaName = areaService!!.getAreaFullNameByAreaId(it.areaId)
                roles = userRoleService!!.findByUserId(supervisionUser.userId)!!
                officeName = iAdministrativeOfficeService!!.getOfficeNameById(officeId)
                businessName = iBusinessService.getBusinessNameById(businessId)
                dutyName = iDutyService.getDutyNameById(supervisionUser.dutyId)

                userLevel = when (supervisionUser.userLevel) {
                    1 -> {
                        if (userRoleService.findByUserId(supervisionUser.userId)!!.mapNotNull { it.name }
                                        .contains(CommonConstant.ROLE_CITY_DEPARTMENT_LEADER))
                            "市级政府"
                        else
                           "市级部门"
                    }
                    2 -> {
                        if (userRoleService.findByUserId(supervisionUser.userId)!!.mapNotNull { it.name }
                                        .contains(CommonConstant.ROLE_COUNTRY_DEPARTMENT_LEADER))
                            "区县级政府"
                        else
                            "区县级部门"
                    }
                    else -> {
                        if (userRoleService.findByUserId(supervisionUser.userId)!!.mapNotNull { it.name }
                                        .contains(CommonConstant.ROLE_TOWN_DEPARTMENT_LEADER))
                            "乡镇级政府"
                        else
                            "乡镇级部门"
                    }
                }
                }
            }
        return supervisionUserVo
    }


    override fun getSupervisionByLevel(userId: String): MutableList<SupervisionUser?>? {

         return iEnterpriseEmployeeService.getOne(KtQueryWrapper(EnterpriseEmployee::class.java).eq(EnterpriseEmployee::userId, userId))?.run {

             ToolUtil.setListToNul(list(KtQueryWrapper(SupervisionUser::class.java).eq(SupervisionUser::areaId, areaId).eq(SupervisionUser::businessId,
                     iEnterpriseUserService!!.getById(enterpriseId)?.businessId)))
        }
    }

    override fun getEnterpriseListByAreaId(enterpriseUserSearchDto: EnterpriseUserSearchDto, pageVo: PageVo?): Result<MutableMap<String, Any?>>? {

        return ToolUtil.setListToNul(iEnterpriseUserService!!.list(KtQueryWrapper(EnterpriseUser::class.java).eq(EnterpriseUser::areaId, securityUtil!!.currUser.areaId)
                .eq(ToolUtil.isNotEmpty(enterpriseUserSearchDto.businessId), EnterpriseUser::businessId, enterpriseUserSearchDto.businessId)
                .orderByDesc(EnterpriseUser::createTime))) ?.run {

            var enterpriseUserList = mapNotNull { iEnterpriseUserService.getEnterpriseUserVo(it!!.id) }.toMutableList()
            enterpriseUserSearchDto.employeeNum?.apply {

                enterpriseUserList = enterpriseUserList.filter { it.headcount == this }.toMutableList()
            }

            ToolUtil.setListToNul(enterpriseUserList)?.run {

                val result: MutableMap<String, Any?> = Maps.newHashMap()
                result["size"] = enterpriseUserList.size
                result["content"] = PageUtil.listToPage(pageVo, enterpriseUserList)
                data(result, "获取数据成功！")

            } ?: error(201, "暂无数据")

        } ?: error(201, "暂无数据")
    }

    override fun getEnterpriseDetail(id: String?): Result<EnterpriseUserDetailVo?>? {

        return iEnterpriseUserService!!.getEnterpriseDetail(id!!)
    }

    override fun forbiddenSupervisionUser(id: Array<out String>): Result<Any?>? {

        id.toList().forEach { i ->

            getById(i)?.let {

                userService!!.get(it.userId)?.apply {

                    when (this.status) {
                        CommonConstant.STATUS_NORMAL -> {

                            this.status = CommonConstant.STATUS_DISABLE
                        }
                        else -> {

                            this.status = CommonConstant.STATUS_NORMAL
                        }
                    }
                }
            }
        }

        return success("禁用用户成功")
    }

    override fun getSecurityAdvisorDetail(id: String?): Result<SecurityAdvisorDetailVo?>? {

        return data(iSecurityAdvisorService!!.getSecurityAdvisorDetailVo(id!!), "获取安全顾问详情成功")
    }

    override fun currentUserLevel(): Int? {

        return getOne(KtQueryWrapper(SupervisionUser::class.java).eq(SupervisionUser::userId, securityUtil!!.currUser.id))?.userLevel ?: 0
    }

    override fun getSupervisionMessageByArea(): Result<List<UserCommonVo>>? {

        return this.list(KtQueryWrapper(SupervisionUser::class.java)
                .eq(SupervisionUser::areaId, securityUtil!!.currUser.areaId)
                .orderByDesc(SupervisionUser::createTime))?.run {


            val supervisionList = filter { iUserRoleService.findByUserId(it?.userId).map { it.id }.contains(when (iAreaService.getById(securityUtil!!.currUser.areaId)?.areaLevel) {

                2 -> {
                    CommonConstant.ROLE_COUNTY_REPORT
                }
                else -> {
                    CommonConstant.ROLE_TOWN_REPORT
                }
            } ) }

            if (ToolUtil.isNotEmpty(ToolUtil.setListToNul(supervisionList))) {

                return data(supervisionList.mapNotNull { UserCommonVo().apply { ToolUtil.copyProperties(userService!!.get(it?.userId), this) }  }, "获取数据成功！")
            } else {

                error(201, "暂无数据！")
            }

        }
    }

    override fun createSecurityAdvisor(securityAdvisorDto: SecurityAdvisorDto?): Result<Any?>? {

        return iSecurityAdvisorService!!.createSecurityAdvisor(securityAdvisorDto)
    }

    override fun updateSecurityAdvisor(securityAdvisorDto: SecurityAdvisorDto): Result<Any?>? {

        return iSecurityAdvisorService!!.updateSecurityAdvisor(securityAdvisorDto)
    }

    override fun removeSecurityAdvisor(ids: Array<out String>?): Result<Any?>? {

        return iSecurityAdvisorService!!.removeSecurityAdvisor(ids)
    }

    override fun forbiddenSecurityAdvisor(ids: Array<out String>?): Result<Any?>? {

        return iSecurityAdvisorService!!.forbiddenSecurityAdvisor(ids)
    }

    override fun securityAdvisorList(pageVo: PageVo): Result<MutableMap<String, Any?>?>? {

        return iSecurityAdvisorService!!.securityAdvisorList(pageVo)
    }

}